package grails.company

import grails.converters.JSON
import grails.test.mixin.*
import grails.test.mixin.domain.DomainClassUnitTestMixin
import org.junit.*

/**
 * See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
 */
@TestFor(OrganizationController)
@Mock(Organization)
class OrganizationControllerTests {

    @Before
    void setUp() {
        new Organization(title: 'ACME', description: 'desc1').save()
        new Organization(title: 'ZooBoo', description: 'desc2').save()
        params.data = [:]
    }

    private assertResponseSuccess(boolean success = true) {
        def json = JSON.parse(response.contentAsString)
        assertNotNull json
        assertEquals(json.success, success)
    }

    void testList() {
        controller.list();

        assertNotNull response.contentAsString
        def json = JSON.parse(response.contentAsString)
        assertNotNull json
        assertEquals(json.success, true)
        assertEquals(json.data[0].title, 'ACME')
        assertEquals(json.data[0].description, 'desc1')
    }

    void testListEmpty() {
        Organization.metaClass.static.list = {-> [] }

        controller.list()

        assertResponseSuccess(false)
    }

    void testViewEmpty() {
        Organization.metaClass.static.list = {-> [] }

        controller.view()

        assertResponseSuccess(false)
    }

    void testViewNoIdSet() {
        controller.view()

        assertNotNull response.contentAsString
        def json = JSON.parse(response.contentAsString)
        assertNotNull json
        assertEquals(json.success, true)
        assertEquals(json.data[0].title, 'ACME')
        assertEquals(json.data[0].description, 'desc1')
        assertEquals(json.data[1].title, 'ZooBoo')
        assertEquals(json.data[1].description, 'desc2')
    }

    void testViewInvalidIdSet() {
        params.data.id = -1

        controller.view()

        assertResponseSuccess(false)
    }

    void testViewValidIdSet() {
        params.data.id = Organization.findByTitle('ZooBoo').id

        controller.view()

        assertNotNull response.contentAsString
        def json = JSON.parse(response.contentAsString)
        assertNotNull json
        assertEquals(json.success, true)
        assertEquals(json.data.title, 'ZooBoo')
        assertEquals(json.data.description, 'desc2')
        assertEquals(json.data.id, params.data.id)
    }

    void testUpdateNoIdSet() {
        controller.update()

        assertResponseSuccess(false)
    }

    void testUpdateNoTitleSet() {
        params.data.id = Organization.findByTitle('ZooBoo')

        controller.update()

        assertResponseSuccess(false)
    }

    void testUpdateInvalidIdSet() {
        params.data.id = -1

        controller.update()

        assertResponseSuccess(false)
    }

    void testUpdateValidSet() {
        params.data.id = Organization.findByTitle('ZooBoo').id
        params.data.title = 'BooZoo'
        params.data.description = 'NewDescription'

        controller.update()

        assertNotNull response.contentAsString
        def json = JSON.parse(response.contentAsString)
        assertNotNull json
        assertEquals(json.success, true)
        assertNotNull Organization.findByTitle(params.data.title);
        assertNotNull Organization.findByDescription(params.data.description)
    }

    void testDeleteNoIdSet() {
        controller.delete()

        assertResponseSuccess(false)
    }

    void testDeleteInvalidIdSet() {
        params.data.id = -1

        controller.delete()

        assertResponseSuccess(false)
    }

    void testDeleteValidIdSet() {
        params.data.id = Organization.findByTitle('ACME').id

        controller.delete()

        assertResponseSuccess()
        assertNull Organization.findByTitle('ACME');
    }

    void testCreateNoTitleSet() {
        controller.create()

        assertResponseSuccess(false)
    }

    void testCreateValidate() {
        Organization.metaClass.validate = {-> false }
        params.data.title = 'NewOrganizationTitle'

        controller.create()

        assertResponseSuccess(false)
    }

    void testCreateSave() {
        Organization.metaClass.save = {-> false }
        params.data.title = 'NewOrganizationTitle'

        controller.create()

        assertResponseSuccess(false)
    }

    void testCreateValid() {
        params.data.title = 'NewOrganizationTitle'
        params.data.description = 'NewDescription'

        controller.create()

        assertResponseSuccess()
        def org = Organization.findByTitle(params.data.title)
        assertNotNull org
        assertEquals(org.title, params.data.title)
        assertEquals(org.description, params.data.description)
        def json = JSON.parse(response.contentAsString)
        assertEquals(json.data.id, org.id)
        assertEquals(json.data.title, org.title)
        assertEquals(json.data.description, org.description)
    }
}
